home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / fwcp / src / scrn.c < prev    next >
Text File  |  1995-03-31  |  19KB  |  859 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <stdarg.h>
  4.  
  5. #ifdef    MSDOS
  6. #include    <jctype.h>
  7. #include    <dos.h>
  8. #else
  9. #include    <sys/types.h>
  10. #include    <sys/ioctl.h>
  11. #include    <sys/termio.h>
  12. #include    <sys/tty.h>
  13. #endif
  14.  
  15. #include    "defs.h"
  16.  
  17. typedef    struct    {
  18.     char    at;
  19.     char    ch;
  20.     } VRAM;
  21.  
  22. static    VRAM    *vram = NULL;
  23. static    VRAM    *dram = NULL;
  24. static    VRAM    *sram = NULL;
  25.  
  26. static    char    tc_ent[2048];
  27. static    char    tc_buf[2048];
  28. static    int    R7;
  29. static    char    *CD, *CE, *CL,
  30.         *CM, *HO, *LL,
  31.         *LE, *ND, *DO, *UP,
  32.         *DC, *IC, *DL, *AL,
  33.         *MB, *MD, *MR,
  34.         *ME, *SA,
  35.         *SO, *SX, *SM, *SE,
  36.         *SF, *SR,
  37.         *VB,
  38.         *VI, *VE;
  39.  
  40.     int    lines_max = 0;
  41.     int    cols_max = 0;
  42.  
  43. static    int    lines_sys = 0;
  44. static    int    now_at = 0;
  45. static    int    now_x = 0;
  46. static    int    now_y = 0;
  47. static    int    scr_ofs = 0;
  48. static    int    cur_dsp = TRUE;
  49. static    int    back_x, back_y;
  50. static    int    save_flag = FALSE;
  51.  
  52.     char    *getenv();
  53.     char    *tgetstr();
  54.     char    *tgoto();
  55.     void    setkey();
  56.     void    SYSLINE();
  57.  
  58. static    struct    {
  59.     int    code;
  60.     char    *cap;
  61.     } key_tab[] = {
  62.         { 0x8001,    "k1" },        /* PF1 */
  63.         { 0x8002,    "k2" },        /* PF2 */
  64.         { 0x8003,    "k3" },        /* PF3 */
  65.         { 0x8004,    "k4" },        /* PF4 */
  66.         { 0x8005,    "k5" },        /* PF5 */
  67.         { 0x8006,    "k6" },        /* PF6 */
  68.         { 0x8007,    "k7" },        /* PF7 */
  69.         { 0x8008,    "k8" },        /* PF8 */
  70.         { 0x8009,    "k9" },        /* PF9 */
  71.         { 0x800A,    "k;" },        /* PF10 */
  72.         { 0x800B,    "F1" },        /* PF11 */
  73.         { 0x800C,    "F2" },        /* PF12 */
  74.         { 0x800D,    "F3" },        /* PF13 */
  75.         { 0x800E,    "F4" },        /* PF14 */
  76.         { 0x800F,    "F5" },        /* PF15 */
  77.         { 0x8010,    "F6" },        /* PF16 */
  78.         { 0x8011,    "F7" },        /* PF17 */
  79.         { 0x8012,    "F8" },        /* PF18 */
  80.         { 0x8013,    "F9" },        /* PF19 */
  81.         { 0x8014,    "F;" },        /* PF20 */
  82.         { 0x001C,    "kr" },        /* RIGHT */
  83.         { 0x001D,    "kl" },        /* LEFT */
  84.         { 0x001E,    "ku" },        /* UP */
  85.         { 0x001F,    "kd" },        /* DOWN */
  86.         { 0x007F,    "kD" },        /* DEL */
  87.         { 0x0000,    NULL },
  88.     };
  89.  
  90. static    int    tput_len = 0;
  91. static    char    tput_buf[512];
  92.  
  93. static    void    tflush()
  94. {
  95. #ifdef    MSDOS
  96.     char far *p;
  97.     union REGS reg;
  98.     struct SREGS seg;
  99.  
  100.     p = tput_buf;
  101.     reg.h.ah = 0x1E;
  102.     reg.x.cx = tput_len;
  103.     seg.ds   = FP_SEG(p);
  104.     reg.x.di = FP_OFF(p);
  105.     int86x(0x91, ®, ®, &seg);
  106.     tput_len = 0;
  107. #else
  108.     fflush(stdout);
  109. #endif
  110. }
  111. static    void    tputc(int code)
  112. {
  113. #ifdef    MSDOS
  114.     if ( tput_len >= 512 )
  115.     tflush();
  116.     tput_buf[tput_len++] = code;
  117. #else
  118.     putchar(code);
  119. #endif
  120. }
  121. int    SCRNINIT(char *ent)
  122. {
  123.     int     n;
  124.     char    *term;
  125.     char    *ptr = tc_buf;
  126.     char    *p, *s;
  127. #ifndef    MSDOS
  128.     struct winsize winsize;
  129. #endif
  130.  
  131.     if ( (term = ent) == NULL && (term = getenv("TERM")) == NULL )
  132.     return ERR;
  133.  
  134.     if ( tgetent(tc_ent, term) < 0 )
  135.     return ERR;
  136.  
  137. #ifdef    MSDOS
  138.     lines_max = tgetnum("li");
  139.     cols_max  = tgetnum("co");
  140.  
  141.     if ( (p = getenv("LINES")) != NULL )
  142.     lines_max = atoi(p);
  143.     if ( (p = getenv("COLS")) != NULL )
  144.     cols_max = atoi(p);
  145. #else
  146.     if( ioctl(1, TIOCGWINSZ, &winsize) != -1 ) {
  147.         lines_max = winsize.ws_row;
  148.         cols_max  = winsize.ws_col;
  149.     } else {
  150.         lines_max = tgetnum("li");
  151.         cols_max  = tgetnum("co");
  152.  
  153.         if ( (p = getenv("LINES")) != NULL )
  154.         lines_max = atoi(p);
  155.         if ( (p = getenv("COLUMNS")) != NULL )
  156.         cols_max = atoi(p);
  157.         if ( (p = getenv("COLS")) != NULL )
  158.             cols_max = atoi(p);
  159.     }
  160. #endif
  161.  
  162.     if ( lines_max <= 0 || lines_max >= 160 )
  163.     lines_max = 24;
  164.     if ( cols_max <= 0  || cols_max >= LINSIZ )
  165.     cols_max = 80;
  166.  
  167.     lines_sys = lines_max - 1;
  168. #ifndef    MSDOS
  169.     lines_max--;
  170. #endif
  171.  
  172.     CD = tgetstr("cd", &ptr);    /* Clear to end of display.    */
  173.     CE = tgetstr("ce", &ptr);    /* Clear to end of line.    */
  174.     CL = tgetstr("cl", &ptr);    /* Clear screen and home cursor    */
  175.  
  176.     CM = tgetstr("cm", &ptr);    /* Screen-relative cursor motion*/
  177.  
  178.     HO = tgetstr("ho", &ptr);    /* Home cursor.            */
  179.     LL = tgetstr("ll", &ptr);    /* Last line, first column    */
  180.  
  181.     LE = tgetstr("le", &ptr);    /* Move cursor left one pos.    */
  182.     ND = tgetstr("nd", &ptr);    /* Move cursor right one pos.    */
  183.     DO = tgetstr("do", &ptr);    /* Down one line.        */
  184.     UP = tgetstr("up", &ptr);    /* Up one line.            */
  185.  
  186.     DC = tgetstr("dc", &ptr);    /* Delete character        */
  187.     IC = tgetstr("ic", &ptr);    /* Insert character        */
  188.     DL = tgetstr("dl", &ptr);    /* Delete line.            */
  189.     AL = tgetstr("al", &ptr);    /* Add new blank line.        */
  190.  
  191.     MB = tgetstr("mb", &ptr);    /* Turn on blinking attribute.    */
  192.     MD = tgetstr("md", &ptr);    /* Turn on bold attribute.    */
  193.     MR = tgetstr("mr", &ptr);    /* Turn on reverse attibute.    */
  194.     ME = tgetstr("me", &ptr);    /* Turn off all attributes.    */
  195.  
  196.     SA = tgetstr("sa", &ptr);    /* Define the video attributes.    */
  197.     SO = tgetstr("so", &ptr);    /* Begin standout mode.        */
  198.     SX = tgetstr("sx", &ptr);    /* Begin error mode.        */
  199.     SM = tgetstr("sm", &ptr);    /* Begin message mode.        */
  200.     SE = tgetstr("se", &ptr);    /* End standout mode.        */
  201.  
  202.     SF = tgetstr("sf", &ptr);    /* Scroll text up.        */
  203.     SR = tgetstr("sr", &ptr);    /* Scroll text down.        */
  204.  
  205.     VB = tgetstr("vb", &ptr);    /* Visible bell            */
  206.  
  207.     VI = tgetstr("vi", &ptr);    /* Cursor Display Off        */
  208.     VE = tgetstr("ve", &ptr);    /* Cursor Display On        */
  209.  
  210.     R7 = tgetflag("r7");    /* FMR70 Ext Kanji Code        */
  211.  
  212.     for ( n = 0 ; key_tab[n].cap != NULL ; n++ ) {
  213.     s = ptr;
  214.     if ( (p = tgetstr(key_tab[n].cap, &s)) != NULL )
  215.         setkey(key_tab[n].code, p);
  216.     }
  217.  
  218.     if ( CL == NULL || CM == NULL || CE == NULL )
  219.     return ERR;
  220.  
  221.     if ( (vram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL ||
  222.          (dram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL ||
  223.          (sram = (VRAM *)malloc(sizeof(VRAM)*cols_max*lines_max)) == NULL )
  224.     return ERR;
  225.  
  226.     memset(vram, 0, sizeof(VRAM) * cols_max * lines_max);
  227.     memset(dram, 0, sizeof(VRAM) * cols_max * lines_max);
  228.  
  229.     tputs(CL, 1, tputc);
  230.     tflush();
  231.  
  232.     cur_dsp = TRUE;
  233.  
  234.     return FALSE;
  235. }
  236. void    FLUSH()
  237. {
  238.     int n, i;
  239.     int x, y;
  240.     int sx = (-1);
  241.     int sy = (-1);
  242.     int at = 0;
  243.     VRAM *vp, *dp;
  244.  
  245.     vp = vram;
  246.     dp = dram;
  247.  
  248.     if ( cur_dsp == TRUE && VI != NULL )
  249.     tputs(VI, 1, tputc);
  250.  
  251.     if ( scr_ofs > 0 && scr_ofs < (lines_max / 2) ) {
  252.     memcpy(&(dram[0 * cols_max]),
  253.            &(dram[scr_ofs * cols_max]),
  254.         sizeof(VRAM) * (lines_max - scr_ofs) * cols_max);
  255.         memset(&(dram[(lines_max - scr_ofs) * cols_max]), 0,
  256.         sizeof(VRAM) * scr_ofs * cols_max);
  257.  
  258.     tputs((HO != NULL ? HO : tgoto(CM, 0, 0)), 1, tputc);
  259.     while ( scr_ofs-- > 0 )
  260.         tputs(DL, 1, tputc);
  261.     if ( lines_max == lines_sys )
  262.         SYSLINE(NULL);
  263.  
  264.     } else if ( scr_ofs < 0 && (0 - scr_ofs) < (lines_max / 2) ) {
  265.         for ( y = lines_max - 1 ; y >= (0 - scr_ofs) ; y-- )
  266.         memcpy(&(dram[y * cols_max]),
  267.                &(dram[(y + scr_ofs) * cols_max]), sizeof(VRAM) * cols_max);
  268.         memset(&(dram[0 * cols_max]), 0,
  269.         sizeof(VRAM) * (0 - scr_ofs) * cols_max);
  270.  
  271.     tputs((HO != NULL ? HO : tgoto(CM, 0, 0)), 1, tputc);
  272.     while ( scr_ofs++ < 0 )
  273.         tputs(AL, 1, tputc);
  274.     if ( lines_max == lines_sys )
  275.         SYSLINE(NULL);
  276.     }
  277.     scr_ofs = 0;
  278.  
  279. #if    1
  280.     for ( y = 0 ; y < lines_max ; y++ ) {
  281.     for ( x = 0 ; x < cols_max ; x++ ) {
  282.         if ( vp->ch != dp->ch || vp->at != dp->at ) {
  283.         if ( (vp->at & 0x40) != 0 ) {
  284.             x--; vp--; dp--;
  285.             if ( (vp->at & 0x80) == 0 ) {
  286.                 x++; vp++; dp++;
  287.             vp->at &= 0xBF;
  288.             }
  289.         }
  290.         if ( sx != x || sy != y ) {
  291.             if ( sy == y && (sx + 5) >= x && ND != NULL ) {
  292.             while ( sx++ < x )
  293.                 tputs(ND, 1, tputc);
  294.             } else
  295.             tputs(tgoto(CM, x, y), 1, tputc);
  296.             sx = x;
  297.             sy = y;
  298.         }
  299.         if ( (vp->at & 0x3F) != at ) {
  300.             n = vp->at & 0x3F;
  301.             if ( (at & 0x07) != 0 && ME != NULL ) {
  302.             at = 0;
  303.             tputs(ME, 1, tputc);
  304.             }
  305.             if ( (n & 0x01) != 0 && MB != NULL && ME != NULL )
  306.             tputs(MB, 1, tputc);
  307.             if ( (n & 0x02) != 0 && MD != NULL && ME != NULL )
  308.             tputs(MD, 1, tputc);
  309.             if ( (n & 0x04) != 0 && MR != NULL && ME != NULL )
  310.             tputs(MR, 1, tputc);
  311.  
  312.             if ( (n & 0x38) != (at & 0x38) ) {
  313.             switch(n & 0x18) {
  314.             case 0x00:
  315.                 if ( SE != NULL )
  316.                 tputs(SE, 1, tputc);
  317.                 break;
  318.             case 0x08:
  319.                 if ( SO != NULL )
  320.                 tputs(SO, 1, tputc);
  321.                 break;
  322.             case 0x10:
  323.                 if ( SX != NULL )
  324.                 tputs(SX, 1, tputc);
  325.                 break;
  326.             case 0x18:
  327.                 if ( SM != NULL )
  328.                 tputs(SM, 1, tputc);
  329.                 break;
  330.             }
  331.             }
  332.             at = n;
  333.         }
  334.         if ( (vp[0].at & 0x80) != 0 && (vp[1].at & 0x40) != 0 ) {
  335.             tputc(vp[0].ch);
  336.             tputc(vp[1].ch);
  337.             dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
  338.             dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
  339.             sx+=2;
  340.             x++;
  341.             
  342.         } else {
  343.             if ( vp->ch == 0 && CE != NULL &&
  344.                 memcmp(vp, vp + 1,
  345.                 sizeof(VRAM) * (cols_max - x - 1)) == 0 ) {
  346.             tputs(CE, 1, tputc);
  347.             n = cols_max - x;
  348.             memcpy(dp, vp, sizeof(VRAM) * n);
  349.             x += n;
  350.             vp += n;
  351.             dp += n;
  352.             } else {
  353.             n = (vp->ch == 0 ? ' ':vp->ch) & 0xFF;
  354. #ifdef    MSDOS
  355.             if ( n < ' ' || iskanji(n) )
  356.                 tputc(033);
  357. #endif
  358.             tputc(n);
  359.             dp->at = vp->at;
  360.             dp->ch = vp->ch;
  361.             vp++;
  362.             dp++;
  363.             sx++;
  364.             }
  365.         }
  366.         } else {
  367.         vp++;
  368.         dp++;
  369.         }
  370.     }
  371.     }
  372.  
  373. #else
  374.     for ( y = 0 ; y < lines_max ; y++ ) {
  375.     vp = &(vram[y * cols_max]);
  376.     dp = &(dram[y * cols_max]);
  377.     for ( x = 0 ; x < cols_max ; x++ ) {
  378.         if ( vp[x].ch != dp[x].ch || vp[x].at != dp[x].at )
  379.         break;
  380.     }
  381.     if ( x >= cols_max )
  382.         continue;
  383.  
  384.     for ( i = cols_max - 1 ; i > x ; i-- ) {
  385.         if ( vp[i].ch != dp[i].ch || vp[i].at != dp[i].at )
  386.         break;
  387.     }
  388.  
  389.     vp += x;
  390.     dp += x;
  391.     tputs(tgoto(CM, x, y), 1, tputc);
  392.  
  393.     for ( ; x <= i ; x++ ) {
  394.         if ( (vp->at & 0x40) != 0 ) {
  395.         x--; vp--; dp--;
  396.         if ( (vp->at & 0x80) == 0 ) {
  397.             x++; vp++; dp++;
  398.             vp->at &= 0xBF;
  399.         }
  400.         }
  401.  
  402.         if ( (vp->at & 0x0F) != at ) {
  403.         n = vp->at & 0x0F;
  404.         if ( (at & 0x07) != 0 && ME != NULL ) {
  405.             at = 0;
  406.             tputs(ME, 1, tputc);
  407.         }
  408.         if ( (n & 0x01) != 0 && MB != NULL && ME != NULL )
  409.             tputs(MB, 1, tputc);
  410.         if ( (n & 0x02) != 0 && MD != NULL && ME != NULL )
  411.             tputs(MD, 1, tputc);
  412.         if ( (n & 0x04) != 0 && MR != NULL && ME != NULL )
  413.             tputs(MR, 1, tputc);
  414.  
  415.         if ( (n & 0x08) != (at & 0x08) &&
  416.                 SO != NULL && SE != NULL )
  417.             tputs(((n & 0x08) ? SO : SE), 1, tputc);
  418.         at = n;
  419.         }
  420.  
  421.         if ( (vp[0].at & 0x80) != 0 && (vp[1].at & 0x40) != 0 ) {
  422.         tputc(vp[0].ch);
  423.         tputc(vp[1].ch);
  424.         dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
  425.         dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
  426.         x++;
  427.             
  428.         } else {
  429.         n = (vp->ch == 0 ? ' ':vp->ch) & 0xFF;
  430. #ifdef    MSDOS
  431.         if ( n < ' ' || iskanji(n) )
  432.             tputc(033);
  433. #endif
  434.         tputc(n);
  435.         dp->at = vp->at; dp->ch = vp->ch; vp++; dp++;
  436.         }
  437.     }
  438.     }
  439. #endif
  440.  
  441.     if ( (at & 0x07) != 0 && ME != NULL )
  442.     tputs(ME, 1, tputc);
  443.     if ( (at & 0x08) != 0 && SE != NULL )
  444.     tputs(SE, 1, tputc);
  445.  
  446.     tputs(tgoto(CM, now_x, now_y), 1, tputc);
  447.  
  448.     if ( cur_dsp == TRUE && VE != NULL )
  449.     tputs(VE, 1, tputc);
  450.  
  451.     tflush();
  452. }
  453. void    REFLUSH()
  454. {
  455.     memset(dram, 0xFF, sizeof(VRAM) * (cols_max * lines_max - 1));
  456. }
  457. void    SAVESCREEN()
  458. {
  459.     if ( save_flag == FALSE )
  460.     memcpy(sram, vram, sizeof(VRAM) * cols_max * lines_max);
  461.     save_flag = TRUE;
  462. }
  463. void    LOADSCREEN()
  464. {
  465.     memcpy(vram, sram, sizeof(VRAM) * cols_max * lines_max);
  466.     save_flag = FALSE;
  467. }
  468. void    SAVECUR()
  469. {
  470.     back_x = now_x;
  471.     back_y = now_y;
  472. }
  473. void    LOADCUR()
  474. {
  475.     now_x = back_x;
  476.     now_y = back_y;
  477. }
  478. void    PUTANK(int ch)
  479. {
  480.     if ( ch == 0x20 )
  481.     ch = 0;
  482.  
  483.     vram[now_x + now_y * cols_max].at = now_at;
  484.     vram[now_x + now_y * cols_max].ch = ch;
  485.  
  486.     if ( ++now_x >= cols_max ) {
  487.     now_x = 0;
  488.     if ( ++now_y >= lines_max )
  489.         now_y = lines_max - 1;
  490.     }
  491. }
  492. void    PUTC(int ch)
  493. {
  494.     PUTANK(ch);
  495. }
  496. void    PUTKAN(int ch)
  497. {
  498.     int n;
  499.     static struct {
  500.     int    jisR70;
  501.     int    jis83;
  502.     } jistab[]={
  503.     { 0xEF64,    0x84aa },
  504.     { 0xEF65,    0x84ab },
  505.     { 0xEF60,    0x84ac },
  506.     { 0xEF61,    0x84ad },
  507.     { 0xEF63,    0x84ae },
  508.     { 0xEF62,    0x84af },
  509.  
  510.     { 0xEF88,    0x84a5 },
  511.     { 0xEF89,    0x84a6 },
  512.     { 0xEF8A,    0x84a7 },
  513.     { 0xEF87,    0x84a8 },
  514.     { 0xEF8B,    0x84a9 },
  515.  
  516.     { 0xEF85,    0x849f },
  517.     { 0xEF86,    0x84a0 },
  518.     { 0xEF81,    0x84a1 },
  519.     { 0xEF82,    0x84a2 },
  520.     { 0xEF84,    0x84a3 },
  521.     { 0xEF83,    0x84a4 },
  522.  
  523.     { 0xEF67,    0x84b0 },
  524.     { 0xEF68,    0x84b1 },
  525.     { 0xEF69,    0x84b2 },
  526.     { 0xEF66,    0x84b3 },
  527.     { 0xEF6A,    0x84b4 },
  528.  
  529.     { 0xEF74,    0x84b5 },
  530.     { 0xEF76,    0x84b6 },
  531.     { 0xEF78,    0x84b7 },
  532.     { 0xEF72,    0x84b8 },
  533.     { 0xEF7A,    0x84b9 },
  534.  
  535.     { 0,0 }
  536.     };
  537.  
  538.     if ( R7 != TRUE ) {
  539.     for ( n = 0 ; jistab[n].jisR70 != 0 ; n++ ) {
  540.         if ( ch == jistab[n].jisR70 ) {
  541.         ch = jistab[n].jis83;
  542.         break;
  543.         }
  544.     }
  545.     }
  546.  
  547.     if ( (now_x + 2) > cols_max ) {
  548.     now_x = 0;
  549.     if ( ++now_y >= lines_max )
  550.         now_y = lines_max - 1;
  551.     }
  552.  
  553.     vram[now_x + now_y * cols_max].at = now_at | 0x80;
  554.     vram[now_x + now_y * cols_max].ch = ch >> 8;
  555.     now_x++;
  556.     vram[now_x + now_y * cols_max].at = now_at | 0x40;
  557.     vram[now_x + now_y * cols_max].ch = ch & 0xFF;
  558.     now_x++;
  559.  
  560.     if ( now_x >= cols_max ) {
  561.     now_x = 0;
  562.     if ( ++now_y >= lines_max )
  563.         now_y = lines_max - 1;
  564.     }
  565. }
  566. void    PUTS(char *str)
  567. {
  568.     while ( *str != '\0' ) {
  569.     if ( iskanji(str[0]) && iskanji2(str[1]) ) {
  570.         PUTKAN(((str[0] & 0xFF) << 8) | (str[1] & 0xFF));
  571.         str += 2;
  572.     } else
  573.         PUTANK(*(str++));
  574.     }
  575. }
  576. void    FPUTS(char *form, ...)
  577. {
  578.     va_list arg;
  579.     char    tmp[128];
  580.  
  581.     va_start(arg, form);
  582.     vsprintf(tmp, form, arg);
  583.     va_end(arg);
  584.  
  585.     PUTS(tmp);
  586. }
  587. void    LOCATE(int x, int y)
  588. {
  589.     if ( (now_x = x) >= cols_max )
  590.     now_x = cols_max - 1;
  591.     else if ( now_x < 0 )
  592.     now_x = 0;
  593.     if ( (now_y = y) >= lines_max )
  594.     now_y = lines_max - 1;
  595.     else if ( now_y < 0 )
  596.     now_y = 0;
  597. }
  598. void    TOPSCR()
  599. {
  600.     now_x = now_y = 0;
  601. }
  602. void    BTMSCR()
  603. {
  604.     now_x = 0;
  605.     now_y = lines_max - 1;
  606. }
  607. void    INSLINE()
  608. {
  609.     int y;
  610.  
  611.     for ( y = lines_max - 1 ; y > now_y ; y-- )
  612.     memcpy(&(vram[y * cols_max]),
  613.            &(vram[(y - 1) * cols_max]), sizeof(VRAM) * cols_max);
  614.     memset(&(vram[now_y * cols_max]), 0, sizeof(VRAM) * cols_max);
  615. }
  616. void    DELLINE()
  617. {
  618.     int y;
  619.  
  620.     for ( y = now_y ; y < (lines_max - 1) ; y++ )
  621.     memcpy(&(vram[y * cols_max]),
  622.            &(vram[(y + 1) * cols_max]), sizeof(VRAM) * cols_max);
  623.     memset(&(vram[(lines_max - 1) * cols_max]), 0, sizeof(VRAM) * cols_max);
  624. }
  625. void    FORSCROOL()
  626. {
  627.     int y;
  628.  
  629.     for ( y = 0 ; y < (lines_max - 1) ; y++ )
  630.     memcpy(&(vram[y * cols_max]),
  631.            &(vram[(y + 1) * cols_max]), sizeof(VRAM) * cols_max);
  632.     memset(&(vram[(lines_max - 1) * cols_max]), 0, sizeof(VRAM) * cols_max);
  633.     scr_ofs++;
  634. }
  635. void    BAKSCROOL()
  636. {
  637.     int y;
  638.  
  639.     for ( y = lines_max - 1 ; y > 0 ; y-- )
  640.     memcpy(&(vram[y * cols_max]),
  641.            &(vram[(y - 1) * cols_max]), sizeof(VRAM) * cols_max);
  642.     memset(&(vram[0 * cols_max]), 0, sizeof(VRAM) * cols_max);
  643.     scr_ofs--;
  644. }
  645. void    CLS()
  646. {
  647.     memset(vram, 0, sizeof(VRAM) * cols_max * lines_max);
  648.     now_x = now_y = 0;
  649. }
  650. void    ERALINE()
  651. {
  652.     memset(&(vram[now_x + now_y * cols_max]), 0,
  653.     sizeof(VRAM) * (cols_max - now_x));
  654. }
  655. void    ERASCR()
  656. {
  657.     int y;
  658.  
  659.     ERALINE();
  660.     for ( y = now_y + 1 ; y < lines_max ; y++ )
  661.     memset(&(vram[y * cols_max]), 0, sizeof(VRAM) * cols_max);
  662. }
  663. void    BAKSPC(int n)
  664. {
  665.     if ( (now_x -= n) < 0 )
  666.     now_x = 0;
  667. }
  668. void    ATTSET(int n)
  669. {
  670.     while ( n-- > 0 ) {
  671.     vram[now_x + now_y * cols_max].at &= 0xC0;
  672.     vram[now_x + now_y * cols_max].at |= now_at;
  673.     if ( ++now_x >= cols_max ) {
  674.         now_x = 0;
  675.         if ( ++now_y >= lines_max )
  676.             now_y = lines_max - 1;
  677.     }
  678.     }
  679. }
  680. void    BLINKCOL()
  681. {
  682.     now_at |= 0x01;
  683. }
  684. void    BOLDCOL()
  685. {
  686.     now_at |= 0x02;
  687. }
  688. void    REVCOL()
  689. {
  690.     now_at |= 0x04;
  691. }
  692. void    NOMCOL()
  693. {
  694.     now_at &= 0x38;
  695. }
  696. void    ACTCOL()
  697. {
  698.     now_at &= 0x07;
  699.     now_at |= 0x08;
  700. }
  701. void    ERRCOL()
  702. {
  703.     now_at &= 0x07;
  704.     now_at |= 0x10;
  705. }
  706. void    MSGCOL()
  707. {
  708.     now_at &= 0x07;
  709.     now_at |= 0x18;
  710. }
  711. void    STDCOL()
  712. {
  713.     now_at &= 0x07;
  714. }
  715. void    REPCHR(int ch, int n)
  716. {
  717.     while ( n-- > 0 )
  718.     PUTANK(ch);
  719. }
  720. void    CUROFF()
  721. {
  722.     cur_dsp = FALSE;
  723.     if ( VI != NULL )
  724.     tputs(VI, 1, tputc);
  725.     tflush();
  726. }
  727. void    CURON()
  728. {
  729.     cur_dsp = TRUE;
  730.     if ( VE != NULL )
  731.     tputs(VE, 1, tputc);
  732.     tflush();
  733. }
  734. void    BEEP()
  735. {
  736.     if ( VB != NULL )
  737.     tputs(VB, 1, tputc);
  738.     else
  739.     tputc(0x07);
  740.     tflush();
  741. }
  742. #ifdef    MSDOS
  743. int     jis2sjis(chr)
  744. int     chr;
  745. {
  746.     int    hi,lo;
  747.  
  748.     hi = (chr >> 8) & 0xff;
  749.     lo = chr & 0xff;
  750.     if ( (hi & 1) != 0 )
  751.         lo += 0x1F;
  752.     else
  753.         lo += 0x7D;
  754.     if ( lo >= 0x7F )
  755.         lo++;
  756.     hi = (hi - 0x21 >> 1) + 0x81;
  757.     if ( hi > 0x9F )
  758.         hi += 0x40;
  759.     return (hi << 8 | lo);
  760. }
  761. int     sjis2jis(cd)
  762. int     cd;
  763. {
  764.     int    hi,lo;
  765.  
  766.     hi = (cd >> 8) & 0xff;
  767.     lo = cd & 0xff;
  768.     hi -= ( hi <= 0x9f) ? 0x71 : 0xb1;
  769.     hi = hi * 2 +1;
  770.     if ( lo > 0x7f )
  771.         lo--;
  772.     if ( lo >= 0x9e ) {
  773.         lo -= 0x7d;
  774.         hi++;
  775.     }
  776.     else
  777.         lo -= 0x1f;
  778.     return (hi << 8 | lo);
  779. }
  780. void    SYSLINE(char *str)
  781. {
  782.     int     i,n;
  783.     char far *p;
  784.     union REGS regs;
  785.     struct SREGS seg;
  786.     static struct {
  787.     char far    *chr;
  788.     char far    *att;
  789.     } adr_tbl;
  790.     static struct {
  791.     char        mode;
  792.     char        attr;
  793.     short        color;
  794.     } att_buf[80];
  795.     static char        chr_buf[80];
  796.  
  797.     memset(chr_buf, 0, 80);
  798.     memset(att_buf, 0, sizeof(att_buf));
  799.     n = 0;
  800.  
  801.     while ( n < 80 && *str != '\0' ) {
  802.     if ( iskanji(*str) && iskanji2(*(str+1)) ) {
  803.         i = *(str++) << 8;
  804.         i |= (*(str++) & 0xFF);
  805.         i = sjis2jis(i);
  806.         chr_buf[n] = (i >> 8);
  807.         att_buf[n].mode = 1;
  808.         att_buf[n].attr = 0;
  809.         att_buf[n].color = 7;
  810.         n++;
  811.         chr_buf[n] = (i & 0xFF);
  812.         att_buf[n].mode = 3;
  813.         att_buf[n].attr = 0;
  814.         att_buf[n].color = 7;
  815.         n++;
  816.     } else {
  817.         chr_buf[n] = *(str++);
  818.         att_buf[n].mode = 0;
  819.         att_buf[n].attr = 0;
  820.         att_buf[n].color = 7;
  821.         n++;
  822.     }
  823.     }
  824.  
  825.     adr_tbl.chr = (char far *)chr_buf;
  826.     adr_tbl.att = (char far *)att_buf;
  827.  
  828.     p = (char far *)(&adr_tbl);
  829.     regs.h.ah = 0x1F;
  830.     regs.h.al = 1;
  831.     regs.x.cx = 60;
  832.     regs.h.dl = 1;
  833.     seg.ds = FP_SEG(p);
  834.     regs.x.di = FP_OFF(p);
  835.     int86x(0x91,®s,®s,&seg);
  836. }
  837. #else
  838. void    SYSLINE(char *str)
  839. {
  840.     static char *now = "";
  841.  
  842.     if ( str == NULL )
  843.     str = now;
  844.     now = str;
  845.     tputs(tgoto(CM, 0, lines_sys), 1, tputc);
  846.     while ( *str != '\0' )
  847.     tputc(*(str++));
  848.     tputs(CE, 1, tputc);
  849.     tflush();
  850. }
  851. #endif
  852. void    SCRNEND()
  853. {
  854.     SYSLINE("");
  855.     tputs(tgoto(CM, 0, lines_sys), 1, tputc);
  856.     tputs(CE, 1, tputc);
  857.     tflush();
  858. }
  859.